package com.jz.digital.utils;

import android.text.TextUtils;
import android.util.Log;

import com.jz.digital.BuildConfig;
import com.jz.digital.MyAppLocation;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Locale;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingDeque;

/**
 * ================================================
 * Created: WangYong
 * Date: 2024/11/24
 * Description:
 * ================================================
 */
public class LogUtils {
    private static final String LINE_SEP = System.getProperty("line.separator");

    private static final String FILE_NAME_PATTERN = "yyyyMMdd";
    private static final String FILE_TIMESTAMP_PATTERN = "yyyy-MM-dd HH:mm:ss.SSSZ";
    private static final String TAG = "LogUtils";
    private static final String LOG_FILE_PREFIX_NAME = ".log";
    private final static SimpleDateFormat mFileSimpleDateFormat = new SimpleDateFormat(FILE_NAME_PATTERN, Locale.CHINA);
    private static final SimpleDateFormat mLogSimpleDateFormat = new SimpleDateFormat(FILE_TIMESTAMP_PATTERN, Locale.CHINA);
    private final LinkedBlockingDeque<LogBean> mLogQueue = new LinkedBlockingDeque<>();
    private static LogUtils instance;
    private final ExecutorService executorService;
    private static final String path = MyAppLocation.mContext.getFilesDir().getAbsolutePath() + File.separator + "terminal" + File.separator + "Log";

    // 私有构造函数
    private LogUtils() {
        executorService = Executors.newSingleThreadExecutor();
    }

    // 获取单例实例
    public static synchronized LogUtils getInstance() {
        if (instance == null) {
            instance = new LogUtils();
        }
        return instance;
    }

    // 异步写入日志
    public void writeLogAsync(String logContent) {
        if (!BuildConfig.DEBUG || TextUtils.isEmpty(logContent)) {
            return;
        }
        ToastUtils.getInstance().showToast(logContent);
        executorService.execute(() -> {
            LogBean logBean = new LogBean(path, "d", TAG, logContent);
            String logDir = logBean.Path;
            String log = logBean.convertToMessage(logBean.Path, logBean.Level, logBean.Tag, logBean.Text);
            if (createLogFileDir(logDir)) {
                writeToFile(logDir, log);
            } else {
                Log.e(TAG, "createLogFileDir failed:" + logDir);
            }
        });
    }

    // 关闭线程池
    public void shutdown() {
        executorService.shutdown();
    }

    public static void d(String tag, String text) {
        Log.d(tag, text);
    }

    public static void e(String tag, String text) {
        Log.e(tag, text);
    }

    private boolean createLogFileDir(String dir) {
        File file = new File(dir);
        if (!file.exists()) {
            return file.mkdirs();
        }
        return true;
    }

    private void writeToFile(String dirPath, String log) {
        BufferedWriter bw = null;
        String fullPath = dirPath + File.separator + getLogFileName();
        File file = new File(fullPath);
        boolean isFileExist = true;
        if (!file.exists()) {
            try {
                isFileExist = file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
                Log.e(TAG, e.toString());
            }
        }
        if (!isFileExist) {
            Log.e(TAG, "create log file failed!");
            return;
        }

        try {
            bw = new BufferedWriter(new FileWriter(file, true));
            bw.write(log);
        } catch (Exception e) {
            Log.e(TAG, e.toString());
        } finally {
            try {
                if (bw != null) {
                    bw.close();
                }
            } catch (IOException e) {
                Log.e(TAG, e.toString());
            }
        }
    }

    private String getLogFileName() {
        return mFileSimpleDateFormat.format(Calendar.getInstance().getTime()) + LOG_FILE_PREFIX_NAME;
    }

    private static class LogBean {
        String Path;
        String Level;
        String Tag;
        String Text;

        public LogBean(String path, String level, String tag, String text) {
            Path = path;
            Level = level;
            Tag = tag;
            Text = text;
        }

        public String convertToMessage(String dirPath, String logLevel, String tag, String text) {
            if (TextUtils.isEmpty(dirPath) || TextUtils.isEmpty(logLevel) || TextUtils.isEmpty(tag) || TextUtils.isEmpty(text))
                return null;
            if (TextUtils.isEmpty(path)) {
                Log.e(TAG, "getLogPathSdcardDir or dirPath is null");
                return null;
            }
            if (tag.length() < 20) {
                StringBuilder builder = new StringBuilder(tag);
                for (int i = builder.length(); i < 20; i++) {
                    builder.append(" ");
                }
                tag = builder.toString();
            }
            return new StringBuilder().append(logLevel)
                    .append("    [").append(mLogSimpleDateFormat.format(Calendar.getInstance().getTime())).append("]    ")
                    .append("    [").append(tag).append("]    ")
                    .append(text)
                    .append(LINE_SEP)
                    .toString();
        }
    }
}
